package club.mzwh.core.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.TextEscapeUtils;

import club.mzwh.common.util.HttpGetUtil;
import club.mzwh.common.util.StringUtil;

import com.google.code.kaptcha.Constants;

/**
 * 带验证码校验功能的用户名、密码认证过滤器
 * 支持不输入验证码；支持验证码忽略大小写。
 * @author ccx
 * 
 */
public class ValidateCodeUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {

	private boolean postOnly = true;
	private boolean allowEmptyValidateCode = false;
	private String sessionvalidateCodeField = DEFAULT_SESSION_VALIDATE_CODE_FIELD;
	private String validateCodeParameter = DEFAULT_VALIDATE_CODE_PARAMETER;
	public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
	// session中保存的验证码
//	public static final String DEFAULT_SESSION_VALIDATE_CODE_FIELD = "rand";
	public static final String DEFAULT_SESSION_VALIDATE_CODE_FIELD = Constants.KAPTCHA_SESSION_KEY;
	// 输入的验证码
	public static final String DEFAULT_VALIDATE_CODE_PARAMETER = "validateCode";
	
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		//处理授权码
		String code = request.getParameter("code");
		System.out.println("code====="+code);
		
		if (StringUtil.isNotNullOrEmpty(code)) {
			System.out.println("code====="+code);
			String tokenurl = "http://localhost:8080/oauth/token?client_id=TestSSO&grant_type=authorization_code&redirect_uri=http://localhost:8088/sso/j_spring_security_check&client_secret=user123&code="+code;
			String ret;
			try {
				ret = HttpGetUtil.httpGet(tokenurl);
//				final JSONObject jo = JSONObject.fromObject(ret);
				// Place the last username attempted into HttpSession for views
				HttpSession session = request.getSession(false);
				if (session != null || getAllowSessionCreation()) {
					request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY,TextEscapeUtils.escapeEntities("sss"));
				}
				
				UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("dd", "");
				setDetails(request, authRequest);
				
				
				Authentication authentication = new Authentication() {
					
					private static final long serialVersionUID = 1L;

					@Override
					public String getName() {
						// TODO Auto-generated method stub
						return "admin";
					}
					
					@Override
					public void setAuthenticated(boolean arg0) throws IllegalArgumentException {
						// TODO Auto-generated method stub
						
					}
					
					@Override
					public boolean isAuthenticated() {
						// TODO Auto-generated method stub
						return false;
					}
					
					@Override
					public Object getPrincipal() {
						// TODO Auto-generated method stub
						return "s";
					}
					
					@Override
					public Object getDetails() {
						// TODO Auto-generated method stub
						return "sda";
					}
					
					@Override
					public Object getCredentials() {
						// TODO Auto-generated method stub
						return "sss";
					}
					
					@Override
					public Collection<? extends GrantedAuthority> getAuthorities() {
						// TODO Auto-generated method stub
						return new ArrayList();
					}
				};
				
				System.out.println(authentication.getName());
				
				System.out.println("ret==="+ret);
				return authentication;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return SecurityContextHolder.getContext().getAuthentication();
			}
		} else {
			if (postOnly && !request.getMethod().equals("POST")) {
				throw new AuthenticationServiceException("Authentication method not supported: "+ request.getMethod());
			}
		
			/****
			 * 验证码
			 */
			checkValidateCode(request);
			System.out.println("ASDFGHJKKLL");
			String username = obtainUsername(request);
			String password = obtainPassword(request);		
			if(username == null || "".equals(username) || password == null || "".equals(password)){
				throw new AuthenticationServiceException("用户名密码不能为空！");
			}
			username = username.trim();
	
			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
			// Place the last username attempted into HttpSession for views
			HttpSession session = request.getSession(false);
			if (session != null || getAllowSessionCreation()) {
				request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY,TextEscapeUtils.escapeEntities(username));
			}
			//-------登录--------
			System.out.println("------------登录------------:"+session.isNew());
			Enumeration<?> enumeration = session.getAttributeNames();
			// 遍历enumeration
			while (enumeration.hasMoreElements()) {
			  // 获取session的属性名称
			  String name = enumeration.nextElement().toString();
			  // 根据键值取session中的值
			  Object value = session.getAttribute(name);
			  // 打印结果
			  System.out.println("name:" + name + ",value:" + value );
			}
			// Allow subclasses to set the "details" property
			setDetails(request, authRequest);
			System.out.println("PRE CALL loadUserByUsername");
			Authentication authentication= this.getAuthenticationManager().authenticate(authRequest);
			System.out.println("POST CALL loadUserByUsername");
//			UserDetailModel user = (UserDetailModel)authentication.getPrincipal();
			System.out.println("ValidateCodeUsernamePasswordAuthenticationFilter===="+authentication.getName());
			return authentication;
		}
	}

	/**
	 * 
	 * <li>比较session中的验证码和用户输入的验证码是否相等</li>
	 * 
	 */
	protected void checkValidateCode(HttpServletRequest request) {
		String sessionValidateCode = obtainSessionValidateCode(request);
		String validateCodeParameter = obtainValidateCodeParameter(request);
		if (StringUtil.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
			throw new AuthenticationServiceException("验证码错误！");
		}
	}

	private String obtainValidateCodeParameter(HttpServletRequest request) {
		return request.getParameter(validateCodeParameter);
	}

	protected String obtainSessionValidateCode(HttpServletRequest request) {
		Object obj = request.getSession().getAttribute(sessionvalidateCodeField);
		return null == obj ? "" : obj.toString();
	}

	public boolean isPostOnly() {
		return postOnly;
	}

	@Override
	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}

	public String getValidateCodeName() {
		return sessionvalidateCodeField;
	}

	public void setValidateCodeName(String validateCodeName) {
		this.sessionvalidateCodeField = validateCodeName;
	}

	public boolean isAllowEmptyValidateCode() {
		return allowEmptyValidateCode;
	}

	public void setAllowEmptyValidateCode(boolean allowEmptyValidateCode) {
		this.allowEmptyValidateCode = allowEmptyValidateCode;
	}

}
